package com.hzw.saas.service.chat.service;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzw.saas.api.chat.IChatEventService;
import com.hzw.saas.api.chat.IChatGroupService;
import com.hzw.saas.api.chat.IChatUserGroupService;
import com.hzw.saas.api.chat.bo.ChatEventBO;
import com.hzw.saas.api.chat.bo.ChatGroupBO;
import com.hzw.saas.api.chat.bo.ChatUserGroupBO;
import com.hzw.saas.api.chat.query.ChatEventQuery;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.config.util.PageParam;
import com.hzw.saas.common.config.util.PageUtils;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import com.hzw.saas.service.chat.mapper.ChatEventMapper;
import com.hzw.saas.service.chat.model.ChatEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service("chatEventService")
public class ChatEventServiceImpl extends ServiceImpl<ChatEventMapper, ChatEvent> implements IChatEventService, IService<ChatEvent> {

    @Resource(name = "chatGroupService")
    private IChatGroupService chatGroupService;

    @Resource(name = "chatUserGroupService")
    private IChatUserGroupService chatUserGroupService;

    @Autowired
    private ChatEventMapper chatEventMapper;

    @Override
    public IPage<ChatEventBO> findHistoryByUserId(String userId, String groupId, PageParam pageParam) {
        List<ChatUserGroupBO> usersByGroupId = chatUserGroupService.findUsersByGroupId(groupId);
        if (CollectionUtil.isEmpty(usersByGroupId)) {
            return new Page<>();
        }
        Page<ChatEvent> page = this.lambdaQuery().eq(ChatEvent::getTargetGroupId, groupId)
            .eq(ChatEvent::getEventType, 41)
            .orderByDesc(ChatEvent::getMilliSecond)
            .page(pageParam.convert());

        return PageUtils.convert(page, ChatEventBO.class);
    }

    @Override
    public IPage<ChatEventBO> findLatestMsg(String userId, PageParam pageParam) {
        List<ChatUserGroupBO> allGroupByUser = chatUserGroupService.findAllGroupByUser(userId);
        if (CollectionUtil.isEmpty(allGroupByUser)){
            log.debug("用户没有加入群组");
            return new Page<>();
        }
        List<String> collect = allGroupByUser.stream().map(ChatUserGroupBO::getGroupId).collect(Collectors.toList());
        long size = collect.size();
        if (size<pageParam.getSize()){
            pageParam.setSize(size);
        }
        List<ChatEvent> chatHistoryList = chatEventMapper.findChatHistoryList(collect, pageParam.getCurrent() - 1L, pageParam.getSize());
        log.debug("历史聊天侧边栏chatHistoryList ："+chatHistoryList.toString());
        if (CollectionUtil.isEmpty(chatHistoryList)){
            log.debug("用户加入群组后群里还未开始聊天");
            return new Page<>();
        }
        Page<ChatEvent> chatEventPage = new Page<>();
        chatEventPage.setRecords(chatHistoryList);
        chatEventPage.setSize(pageParam.getSize());
        chatEventPage.setCurrent(pageParam.getCurrent());
        chatEventPage.setTotal(size);
//        Page<ChatEvent> page = this.lambdaQuery().in(ChatEvent::getTargetGroupId,collect)
//            .eq(ChatEvent::getEventType,41)
//            .groupBy(ChatEvent::getTargetGroupId)
//            .orderByDesc(ChatEvent::getMilliSecond)
//            .page(pageParam.convert());
        return PageUtils.convert(chatEventPage,ChatEventBO.class);
    }

    @Override
    public String addFriendEvent(String userId, String friendId) {
        return null;
    }

    @Override
    public List<ChatEventBO> findChatEventByTargetId(ChatEventQuery chatEventQuery) {
        return null;
    }

    @Override
    public void addEvent(ChatEventBO chatEventBO) {
        ChatEvent chatEvent = buildEvent(chatEventBO);
        this.save(chatEvent);
    }

    ChatEvent buildEvent(ChatEventBO chatEventBO) {
        AssertUtil.assertThrow("事件必须属性不全，无法新增事件", chatEventBO.getEventType() == null || chatEventBO.getSourceId() == null);
        ChatEvent map = MapperUtil.nf().map(chatEventBO, ChatEvent.class);
        if (map.getPid() == null || "".equals(map.getPid())) {
            map.setPid(SnowFlakeUtil.nextIdStr());
        }
        map.setMilliSecond(System.currentTimeMillis());
        return map;
    }

    @Override
    public void saveBatch(ArrayList<ChatEventBO> chatEventBOS) {
        if (CollectionUtil.isNotEmpty(chatEventBOS)) {
            ArrayList<ChatEvent> chatEvents = new ArrayList<>();
            chatEventBOS.forEach(chatEventBO -> {
                ChatEvent chatEvent = buildEvent(chatEventBO);
                chatEvents.add(chatEvent);
            });
            this.saveBatch(chatEvents);
        }
    }

    @Override
    public void sendMsgEvent(ChatEventBO chatEventBO) {
        if (StrUtil.isBlank(chatEventBO.getPid())) {
            chatEventBO.setPid(SnowFlakeUtil.nextIdStr());
        }
    }

    @Override
    public void refuseEvent(ChatEventBO chatEventBO) {

    }

    @Override
    public void buildCommand(ChatEventBO chatEventBO) {

    }

    @Override
    public void makeSource() {
        List<ChatEvent> list = this.lambdaQuery().eq(ChatEvent::getEventType, 25).list();
        if (CollectionUtil.isNotEmpty(list)){
            List<String> collect = list.stream().map(ChatEvent::getTargetGroupId).collect(Collectors.toList());
            List<ChatGroupBO> byIds = chatGroupService.findByIds(collect);
            if (CollectionUtil.isNotEmpty(byIds)){
                byIds.forEach(chatGroupBO -> {
                    list.forEach(chatEvent -> {
                        if (chatGroupBO.getPid().equals(chatEvent.getTargetGroupId())){
                            chatEvent.setSourceId(chatGroupBO.getCreatorId());
                        }
                    });
                });
                this.updateBatchById(list);
            }
        }
    }

    void sendMsgEvent(String userId, String groupId, String targetId, String msg) {
        ChatEventBO chatEventBO = new ChatEventBO();

    }
}
